import { hashHistory } from 'react-router';
/**
 * 本地存储
 * @param (key,value)
 */
const Tool = {};

Tool.locals = {
  setSession(key, value) { // 存储单个属性
    window.sessionStorage[key] = value;
  },
  getSession(key) { // 读取单个属性
    return window.sessionStorage[key];
  },
  setSessionObject(key, value) { // 存储对象，以JSON格式
    window.sessionStorage.setItem('key', JSON.stringify(value));
  },
  getSessionObject(key) { // 读取对象，以JSON格式
    return JSON.parse(sessionStorage.getItem('key'));
  }
};
/**
 * 发送ajax请求和服务器交互
 * @param {object} mySetting 配置ajax的配置
 */
Tool.ajax = function ajax(mySetting) {
  const setting = {
    url: window.location.pathname, // 默认ajax请求地址
    async: true, // true。默认设置下，所有请求均为异步请求。如果需要发送同步请求，请将此选项设置为 false
    type: 'GET', // 请求的方式
    data: {}, // 发给服务器的数据
    dataType: 'json',
    success(text) { }, // 请求成功执行方法
    error() { }, // 请求失败执行方法
    token: Tool.locals.getSession('token')
  };

  function filter(str) { // 特殊字符转义
    str += ''; // 隐式转换
    str = str.replace(/%/g, '%25');
    str = str.replace(/\+/g, '%2B');
    str = str.replace(/ /g, '%20');
    str = str.replace(/\//g, '%2F');
    str = str.replace(/\?/g, '%3F');
    str = str.replace(/&/g, '%26');
    str = str.replace(/\=/g, '%3D');
    str = str.replace(/#/g, '%23');
    return str;
  }
  const aData = []; // 存储数据
  let sData = ''; // 拼接数据
  // 属性覆盖
  for (const attr in mySetting) {
    // eslint规范 for-in循环中要使用if语句
    // =================================
    if ({}.hasOwnProperty.call(mySetting, attr)) {
      setting[attr] = mySetting[attr];
    }
  }
  for (const attr in setting.data) {
    // eslint规范 for-in循环中要使用if语句
    // =================================
    if ({}.hasOwnProperty.call(setting, attr)) {
      aData.push(`${attr}=${filter(setting.data[attr])}`);
    }
  }
  sData = aData.join('&');
  setting.type = setting.type.toUpperCase();
  const xhr = new XMLHttpRequest();
  try {
    if (setting.type === 'GET') { // get方式请求
      sData = setting.url + '?' + sData;
      xhr.open(setting.type, sData + '&' + new Date().getTime(), setting.async);
      xhr.setRequestHeader('Content-type', 'application/json');
      xhr.setRequestHeader('token', setting.token);
      xhr.send();
    } else { // post方式请求
      xhr.open(setting.type, setting.url, setting.async);
      xhr.setRequestHeader('Content-type', 'application/json');
      xhr.setRequestHeader('token', setting.token);
      xhr.send(JSON.stringify(setting.data));
    }
  } catch (e) {
    return httpEnd ();
  }

  if (setting.async) {
    xhr.addEventListener('readystatechange', httpEnd, false);
  } else {
    httpEnd ();
  }

  function httpEnd() {
    if (xhr.readyState === 4) {
      const head = xhr.getAllResponseHeaders();
      let response = xhr.responseText;
      // 将服务器返回的数据，转换成json

      if (/application\/json/.test(head) || setting.dataType === 'json' && /^(\{|\[)([\s\S])*?(\]|\})$/.test(response)) {
        response = JSON.parse(response);
      }
      if (xhr.status === 200 || xhr.status === 201) {
        response.code === 401 || response.code === 10002 ? hashHistory.push('/login') : setting.success(response, setting, xhr);
      } else {
        setting.error(setting, xhr);
      }
    }
  }
  xhr.end = function () {
    xhr.removeEventListener('readystatechange', httpEnd, false);
  };
  return xhr;
};
/**
 * 封装ajax post请求
 * @param {string} pathname 服务器请求地址
 * @param {object} data     发送给服务器的数据
 * @param {function} success  请求成功执行方法
 * @param {function} error    请求失败执行方法
 */
Tool.post = function (pathname, data, success, error) {
  const setting = {
    url: pathname, // 默认ajax请求地址
    type: 'POST', // 请求的方式
    data: data, // 发给服务器的数据
    success: success || function () { }, // 请求成功执行方法
    error: error || function () { } // 请求失败执行方法
  };
  return Tool.ajax(setting);
};
/**
 * 封装ajax get请求
 * @param {string} pathname 服务器请求地址
 * @param {object} data     发送给服务器的数据
 * @param {function} success  请求成功执行方法
 * @param {function} error    请求失败执行方法
 */
Tool.get = function (pathname, data, success, error) {
  const setting = {
    url: pathname, // 默认ajax请求地址
    type: 'GET', // 请求的方式
    data: data, // 发给服务器的数据
    success: success || function () { }, // 请求成功执行方法
    error: error || function () { } // 请求失败执行方法
  };
  return Tool.ajax(setting);
};

export default Tool;
